#include <wx/textctrl.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include "util.h"
#include "settings.h"
#include "debug.h"

#ifdef TARGET_LINUX
#include <gtk/gtk.h>
#endif

#ifdef TARGET_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <richedit.h>
#endif

class InputStringDialog : public wxDialog
{
private:
    wxTextCtrl *string_box;
    wxString *result_string;

public:
    InputStringDialog(const wxString& caption, const wxString& text, wxString* init_string);
    void OnOK(wxCommandEvent& event);
    void OnCancel(wxCommandEvent& event);

    bool Show();

    DECLARE_EVENT_TABLE()
};

bool InputString(wxString *result, const wxString& text, const wxString& caption)
{
    InputStringDialog *dlg = new InputStringDialog(caption, text, result);
    bool retval = dlg->Show();
    dlg->Destroy();
    return retval;
}

//-----------------------------------------------------------------------------------------
// InputStringDialog implementation

BEGIN_EVENT_TABLE(InputStringDialog, wxDialog)
    EVT_BUTTON(wxID_CANCEL, InputStringDialog::OnCancel)
    EVT_BUTTON(wxID_OK, InputStringDialog::OnOK)
END_EVENT_TABLE()

InputStringDialog::InputStringDialog(const wxString& caption, const wxString& text, wxString* init_string)
        : wxDialog(0, -1, caption, wxDefaultPosition, wxSize(350,200), wxDEFAULT_DIALOG_STYLE)
{
    new wxStaticText(this, -1, text,  wxPoint( 20, 25));
//    capt->SetFont(config->GetDialogFont());

    string_box   = new wxTextCtrl(this, -1, *init_string, wxPoint( 20,  50), wxSize(300, 25));
//    string_box->SetFont(config->GetDialogFont());


    wxButton *button_ok = new wxButton(this, wxID_OK,     wxT("&OK"),     wxPoint( 50, 120), wxSize(100, 30));
//    button_ok->SetFont(config->GetDefaultFont());
    button_ok->SetDefault();
    new wxButton(this, wxID_CANCEL, wxT("&Cancel"), wxPoint(200, 120), wxSize(100, 30));
//    button_cancel->SetFont(config->GetDefaultFont());

    Centre();
    SetEscapeId(wxID_CANCEL);

    this->result_string = init_string;
}

bool InputStringDialog::Show()
{
    string_box->SetFocus();
    return ShowModal()==wxID_OK;
}

void InputStringDialog::OnCancel(wxCommandEvent& event)
{
    EndModal(wxID_CANCEL);
}

void InputStringDialog::OnOK(wxCommandEvent& event)
{
    *result_string      = string_box->GetValue();

    EndModal(wxID_OK);
}

#ifdef TARGET_LINUX
int gtk_wxTextCtrl_GetWrappedHeight(wxTextCtrl *ctrl)
{

    // On wxGTK, wxTextCtrl::GetNumberOfLines returns number of lines in source string, not wrapped to TextView width
    GtkTextView *view = (GtkTextView*)(ctrl->GetConnectWidget());    // nasty trickery
//    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD);

    GtkRequisition req;
    gtk_widget_size_request(GTK_WIDGET(view), &req);
    return req.height;

/*   old experiments - left here for some time, just in case...
   for (int i=0; i<100; i++)
        gtk_main_iteration_do(false);

    gtk_widget_size_request(GTK_WIDGET(view), &req);
    dbg("%req2 = %u\n", req.height);

    int final_height = 0;
    while (!final_height) {

        //GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        //gtk_container_add(GTK_CONTAINER(window), (GtkWidget*)view);

      //g_signal_connect_swapped(G_OBJECT(view), "destroy",  G_CALLBACK(gtk_main_quit), G_OBJECT(view));

        // iterate GTK main loop until we get a meaningful value
        if (!final_height) {
            for (int i=0; i<100; i++)
//                gtk_widget_show_now((GtkWidget*)view);
                gtk_main_iteration_do(false);
        }

        GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
        GtkTextIter iter;
        gtk_text_buffer_get_start_iter(buffer, &iter);
        int lines=1;
        while (gtk_text_view_forward_display_line(view, &iter)) lines++;
        int y, ysize;
        gtk_text_view_get_line_yrange(view, &iter, &y, &ysize);
        final_height = y+ysize;

    }

    return final_height;

#if wxCHECK_VERSION(2,9,0)
//#error This is broken on version >= wx-2.9
#endif
*/

}
#endif

#if defined TARGET_WIN32
int msw_wxTextCtrl_GetWrappedHeight(wxTextCtrl *ctrl, int wrapwidth)
{
    ctrl->Move(0,0);
    int logx, logy;
    HDC hdc = ::GetDC((HWND)ctrl->GetHandle());
    logx = GetDeviceCaps(hdc, LOGPIXELSX);
    logy = GetDeviceCaps(hdc, LOGPIXELSY);

    FORMATRANGE r;
    r.hdc = hdc;
    r.hdcTarget = hdc;
    r.rc.left = 0;
    r.rc.right = (wrapwidth*1440) / logx;       // 1440 twips per inch
    r.rc.top = 0;
    r.rc.bottom = 31000;
    r.rcPage = r.rc;
    r.chrg.cpMin = 0;
    r.chrg.cpMax = -1;
    SendMessage((HWND)ctrl->GetHandle(), EM_FORMATRANGE, 0, (LPARAM)&r);

    int result = (r.rc.bottom * logy) / 1440;

    SendMessage((HWND)ctrl->GetHandle(), EM_FORMATRANGE , 0, 0); //free cache

    return result;
}
#endif
